package cn.kk.fluidcells.cells.mouse.internal;

import cn.kk.fluidcells.cells.keyboard.internal.MediaCodeSupport;

import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;

public class DefaultLowLevelMouseProc implements MouseHookProc, MediaCodeSupport {
    private static final boolean DEBUG = true;
    private final MouseHook mouseHook;

    public DefaultLowLevelMouseProc(MouseHook mouseHook) {
        this.mouseHook = mouseHook;
    }

    @Override
    public LRESULT callback(int nCode, WPARAM wParam, MouseHookStruct lParam) {
        if (nCode >= 0) {
            int x;
            int y;
            switch (wParam.intValue()) {
            case WM_MOUSEMOVE:
                this.mouseHook.on(MouseAction.MOVE, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    // System.out.println("mouseMove: "+x + "/" + y);
                }
                break;
            case WM_LBUTTONDOWN:
                this.mouseHook.on(MouseAction.LEFT_BTN_DOWN, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("lButtonDown: " + x + "/" + y);
                }
                break;
            case WM_LBUTTONUP:
                this.mouseHook.on(MouseAction.LEFT_BTN_UP, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("lButtonUp: " + x + "/" + y);
                }
                break;
            case WM_RBUTTONDOWN:
                this.mouseHook.on(MouseAction.RIGHT_BTN_DOWN, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("rButtonDown: " + x + "/" + y);
                }
                break;
            case WM_RBUTTONUP:
                this.mouseHook.on(MouseAction.RIGHT_BTN_UP, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("rButtonUp: " + x + "/" + y);
                }
                break;
            case WM_MBUTTONDOWN:
                this.mouseHook.on(MouseAction.MIDDLE_BTN_DOWN, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("mButtonDown: " + x + "/" + y);
                }
                break;
            case WM_MBUTTONUP:
                this.mouseHook.on(MouseAction.MIDDLE_BTN_UP, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("mButtonUp: " + x + "/" + y);
                }
                break;
            case WM_XBUTTONDOWN:
                this.mouseHook.on(MouseAction.X_BTN_DOWN, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("xButtonDown: " + x + "/" + y);
                }
                break;
            case WM_XBUTTONUP:
                this.mouseHook.on(MouseAction.X_BTN_UP, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("xButtonUp: " + x + "/" + y);
                }
                break;
            case WM_NCXBUTTONDOWN:
                this.mouseHook.on(MouseAction.NC_BTN_DOWN, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("ncButtonDown: " + x + "/" + y);
                }
                break;
            case WM_NCXBUTTONUP:
                this.mouseHook.on(MouseAction.NC_BTN_UP, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("ncButtonUp: " + x + "/" + y);
                }
                break;
            case WM_NCMOUSEMOVE:
                this.mouseHook.on(MouseAction.NC_MOVE, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    System.out.println("ncMouseMove: " + x + "/" + y);
                }
                break;
            case WM_MOUSEWHEEL:
                this.mouseHook.on(MouseAction.WHEEL, nCode, wParam, lParam);
                if (DEBUG) {
                    x = lParam.pt.x;
                    y = lParam.pt.y;
                    int wheelRotation = lParam.mouseData.intValue() >> 16;
                    System.out.println("mouseWheel: " + x + "/" + y + ", " + wheelRotation);
                }
                break;
            }
        }
        return this.mouseHook.lib.CallNextHookEx(MouseHook.hhk, nCode, wParam, lParam.getPointer());
    }

}
